package com.tyqx.hashchainbiz.controller.wx;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.tyqx.hashchainbean.module.HashIndex;
import com.tyqx.hashchainbean.vo.BlockChainVO;
import com.tyqx.hashchainbiz.service.HashIndexService;
import com.tyqx.hashchainutil.common.BlockData;
import com.tyqx.hashchainutil.common.CryptoUtil;
import com.tyqx.hashchainutil.common.HashValueUtil;
import com.tyqx.hashchainutil.org.app.util.Util;
import hashchainutil.common.Dto;
import hashchainutil.common.DtoUtil;
import hashchainutil.common.EmptyUtils;
import org.hyperledger.fabric.sdk.security.CryptoPrimitives;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/wx/blockChain")
@CrossOrigin
public class WxBlockChainController {

    @Resource
    private MongoTemplate mongoTemplate;

    @Resource
    private HashIndexService hashIndexService;

    @RequestMapping(value = "/wxFileUpChain", method = RequestMethod.POST)
    @ResponseBody
    public Dto wxFileUpChain(@RequestParam("file") MultipartFile file) throws Exception {

        if (file.isEmpty()) {
            return DtoUtil.returnFail("文件不能为空", "100001");
        }
        String msg = "";
        try {
            CryptoPrimitives suite = new CryptoPrimitives();
            suite.init();
            byte[] hashBytes = suite.hash(file.getBytes());
            String hashValue = Base64.getEncoder().encodeToString(hashBytes);
            String userName = "admin55";
            HashIndex hashIndex = HashValueUtil.insertHashValue(hashValue, userName);
            hashIndex.setUserName(userName);
            hashIndex.setRootHashValue(hashValue);
            boolean flag=hashIndexService.insertHashIndex(hashIndex);
            if (EmptyUtils.isNotEmpty(flag)) {
                msg = "信息上链成功";
                return DtoUtil.returnSuccess(msg);
            } else {
                msg = "信息上链失败";
                return DtoUtil.returnSuccess(msg);
            }

        } catch (Exception e) {
            e.printStackTrace();
            msg = "上链失败";
        }


        return DtoUtil.returnSuccess(msg);
    }

    @RequestMapping(value = "/sendFileAuth")
    @ResponseBody
    public Dto sendFileAuth(HttpServletRequest request) throws Exception {

        try {
            String caType = "msp";
            Long orgIndex = 0L;
            String channelName = "hashchainchannel";
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            List<MultipartFile> files = multipartRequest.getFiles("fileAuth");

            MultipartFile file = files.get(0);

            byte[] fileBytes=file.getBytes();
            CryptoPrimitives suite = new CryptoPrimitives();
            suite.init();
            byte[] hashBytes = suite.hash(fileBytes);

            String hashValue = Base64.getEncoder().encodeToString(hashBytes);

            List<HashIndex> hashIndexList = hashIndexService.getHashIndexByHashValue(hashValue);
            HashIndex hashIndex = null;
            if (hashIndexList.size() > 0) {
                hashIndex = hashIndexList.get(0);
            } else {
                return DtoUtil.returnFail("未查询到该交易", "100002");
            }

            String userName=hashIndex.getUserName();

            BlockData blockData = new BlockData();
            Map<String, String> map = blockData.getBlockByNum(hashIndex.getBlockNum(), channelName);
            String blockDataStr = map.get("blockDataStr");
            String blockNum = map.get("blockNum");
            JsonObject blockDataJson = new JsonParser().parse(blockDataStr).getAsJsonObject();
            JsonObject hashItemJson = blockData.getHashItemByTxId(blockDataJson, hashIndex.getTxId());
            String blockHashValue = hashItemJson.get("hashValue").toString();

            blockHashValue = blockHashValue.substring(blockHashValue.indexOf("\"") + 1, blockHashValue.lastIndexOf("\""));
            String blockHashSignature = hashItemJson.get("hashSignature").toString();
            blockHashSignature = blockHashSignature.substring(blockHashSignature.indexOf("\"") + 1, blockHashSignature.lastIndexOf("\""));

            Map<String, Object> pathMap = Util.readUserContext(caType, userName, orgIndex);
            Path clientCertPath = (Path) pathMap.get("clientCertPath");

            CryptoUtil cryptoUtil = new CryptoUtil();

            boolean flag = cryptoUtil.verify(clientCertPath, blockHashSignature, blockHashValue);


            if (flag) {
                BlockChainVO blockChainVO=new BlockChainVO();
                blockChainVO.setTxId(hashIndex.getTxId());
                blockChainVO.setHashValue(blockHashValue);
                blockChainVO.setBlockNum(blockNum);
                blockChainVO.setTxTimeStamp(hashIndex.getTxTimeStamp());
                blockChainVO.setUserName(userName);

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String txTimeStamp = sdf.format(hashIndex.getTxTimeStamp());
                String successMsg="验证区块链成功,数据位于区块:"+blockNum+",上链时间:"+txTimeStamp+",数据签名人:"+userName;
                return DtoUtil.returnSuccess(successMsg);
            } else {
                return DtoUtil.returnFail("验证区块链失败", "100001");
            }

        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("验证区块链错误","100003");
        }
    }
}
